package chat.fullduplex;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * This class contains the refactored loop that reads from the remote endpoint. It is cleverly designed to
 * be used used by BOTH the client and the server. The main element of this is the addition of a 
 * "Local" interface to allow this shared object to call different "quit" logic for the server
 * and the client.
 * 
 * Note the use of a constructor to receive arguments / parameters that the run() loop needs. 
 * This step is necessary as the run():void method definition is fixed by Java (in the Runnable 
 * interface). If you do not respect this definition then the JVM will not find the method.
 * 
 * @author Justin Templemore
 */
public class ReadFromRemote implements Runnable 
{
	// the socket to read from
	private Socket remoteSocket;
	// the local endpoint that provides local-specific logic
	private LocalChatEndPoint local;

	/**
	 * Builds a remote endpoint reader over the provided socket, for the specified local endpoint.
	 * @param remoteSocket
	 * @param local
	 */
	public ReadFromRemote (Socket remoteSocket, LocalChatEndPoint local) 
	{
		this.remoteSocket = remoteSocket;
		this.local = local;
	}
	
	@Override
	public void run() 
	{
		BufferedReader inFromClient = null;
		try 
		{
			inFromClient = new BufferedReader (new InputStreamReader(remoteSocket.getInputStream()));
			String messageFromRemote;
			// continue until the socket is closed (readLine returns null)
			while ((messageFromRemote = inFromClient.readLine()) != null) 
			{
				System.out.println("client says : " + messageFromRemote);
				System.out.print("> ");
				if (messageFromRemote.equalsIgnoreCase ("Bye.")) 
				{
					// on reception of bye, call local quit logic.
					local.quit();
					break;
				}
			}
		} 
		catch (IOException ioe) 
		{
			// If an IOException (network connection lost, etc) occurs, simply quit the client.
			System.out.println("Connection to remote closed.");
			local.quit();
		}
		// Remember : We do not stop a thread. A thread stops when the run() finished.
		// So to stop a thread, do what is necessary to make the run() finish.
		// Generally two ways: Interrupt the IO (close the socket) OR set a shared flag to false 
		System.out.println("Finished ReadFromRemote");
	}
}
